package com.demo.java.OD651_700.OD651;

import java.util.Scanner;
import java.util.Arrays;

/**
 * @author bug菌
 * @Source 公众号：猿圈奇妙屋
 * @des： 【大炮攻城 or 攻城战(A卷-100分)】问题
 * @url： https://blog.csdn.net/weixin_43970743/article/details/147039414
 */
public class OdMain {
    public static int min_num;

    public static void main(String[] args) {
        // 处理输入
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();  // 大炮数量
        int m = in.nextInt();  // 最大攻击次数
        int t = in.nextInt();  // 最大时间

        // 存储每个大炮的攻击力、消耗量和充能时间
        int[] A = new int[n];  // 攻击力
        int[] B = new int[n];  // 每次攻击消耗的量
        int[] C = new int[n];  // 充能时间

        // 读取每个大炮的数据
        for (int i = 0; i < n; i++) {
            A[i] = in.nextInt();  // 攻击力
            B[i] = in.nextInt();  // 每次攻击消耗
            C[i] = in.nextInt();  // 充能时间
        }

        // 初始化DP数组，dp[j]表示使用j单位时间时的最大攻击力
        int[] dp = new int[m + 1];  // 注意dp数组大小为m+1，表示从0到m个时间单位

        // 遍历每个大炮
        for (int i = 0; i < n; i++) {
            // 倒序遍历时间，防止重复使用同一个大炮
            for (int j = m - 1; j >= 0; j--) {
                // 计算当前大炮最多可以攻击的次数
                int count = Math.min((m - j) / B[i], t / C[i]);

                // 对于每次可能的攻击次数k，更新dp数组
                for (int k = 1; k <= count; k++) {
                    // 更新dp[j + k * B[i]]，这是当前使用k次大炮后的最大攻击力
                    dp[j + k * B[i]] = Math.max(dp[j + k * B[i]], dp[j] + k * A[i]);
                }
            }
        }

        // 最终输出在最大时间m内的最大攻击力
        Arrays.sort(dp);  // 排序取最大值
        System.out.println(dp[m]);  // 输出结果
    }
}